package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

// 反射

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	str := `{"name":"张三","age":18}`
	var p Person
	// json 序列化 与 反序列化 使用了反射实现
	_ = json.Unmarshal([]byte(str), &p)
	fmt.Printf("%+v\n", p)

	// 通过 反射 获取 动态类型
	t := reflect.TypeOf(p)
	fmt.Printf("动态类型: %s\n", t)
	fmt.Printf("名称: %s\n", t.Name())
	fmt.Printf("种类: %s\n", t.Kind())
	fmt.Printf("是否为 指针 %t\n", t.Kind() == reflect.Ptr)
	// NumField 获取字段数
	for i := 0; i < t.NumField(); i++ {
		// 获取字段信息
		field := t.Field(i)
		fmt.Printf("字段名: %s, 字段类型: %s, Tag: %s\n", field.Name, field.Type, field.Tag)
	}

	fmt.Println("=========================================================")

	// 通过 反射 获取 原始值信息
	// ValueOf 的 返回值为 Value 类型
	i := 10086
	v := reflect.ValueOf(&i)
	if v.Kind() != reflect.Ptr {
		fmt.Println("要 通过 反射 修改值 必须 传入一个 指针变量")
		return
	}
	// 通过 Elem 获取指针对应的值
	fmt.Printf("值: %v\n", v.Elem())
	// 获取 值 类型种类
	k := v.Elem().Kind()
	switch k {
	case reflect.Int:
		fmt.Printf("值类型: %s, 值: %d\n", reflect.Int, v.Elem().Int())
		v.Elem().SetInt(10010)
	}

	fmt.Printf("通过反射修改后的值为: %d\n", i)
}
